package com.xuyu.common.tool.strategy;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;

@Component
public class StrategyFactory implements ApplicationListener<ContextRefreshedEvent> {

    private static final Map<String, Object> allStrategy = new HashMap<>();


    /**
     * 所有的策略类
     */
    @Autowired
    private List<EsStrategy> esStrategy;


    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        if (CollectionUtils.isEmpty(esStrategy)) {
            return;
        }
        for (EsStrategy item : esStrategy) {
            String strategy = item.strategy();
            allStrategy.put(strategy, item);
        }
    }

    /**
     * 获取所有的策略
     *
     * @param strategy 策略基类
     * @param tClass   转换类型
     * @param <T>      类型
     * @return 实际策略接口
     */
    public static <T> T getStrategy(String strategy, Class<T> tClass) {
        if (StringUtils.isEmpty(strategy) || tClass == null) {
            return null;
        }

        Object o = allStrategy.get(strategy);
        return (T) o;
    }


    /**
     * 获取所有的策略
     *
     * @param strategyPrefix 策略的前缀，如果策略实现类同属于某个功能，建议使用接口的类名作为 String strategy()方法返回的策略名的前缀
     * @param <T>            类型
     * @return 实际策略接口
     */
    public static <T> List<T> getAllStrategyByPrefix(String strategyPrefix, Class<T> tClass) {
        if (StringUtils.isEmpty(strategyPrefix)) {
            return Collections.emptyList();
        }
        List<T> list = new ArrayList<>();
        for (Map.Entry<String, Object> each : allStrategy.entrySet()) {
            String key = each.getKey();
            if (key.startsWith(strategyPrefix)) {
                //符合
                Object o = allStrategy.get(key);
                list.add((T) o);
            }
        }
        return list;
    }


}
